using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;

namespace IUPUI.StellarResults
{
	/// <summary>
	/// Represents an astronomical object.
	/// </summary>
	[Serializable]
	public class AstronomicalObject : Identifiable
	{
		#region Private Properties
		private AstronomicalObjectType m_AstronomicalObjectType;
		private PositionType m_PositionType;
		private double m_Speed;
		private Position m_Position = new Position();
		private double m_Magnitude;
		private string m_Constellation = null;
		private double m_Distance = 0;
		private ININ.Measurement.MetricLengthUnit m_DistanceUnit =
			ININ.Measurement.MetricLengthUnit.Kilometers;

		// Appearance
		private string m_RepresentationColor;
		private int m_DiameterInPixels = 4;
		#endregion Private Properties

		#region Public Properties
		/// <summary>
		/// Gets or sets the type of the astronomical object.
		/// </summary>
		/// <value>The type of the astronomical object.</value>
		[Category("AstronomicalObject")]
		[Description("Gets or sets the type of the astronomical object.")]
		public AstronomicalObjectType AstronomicalObjectType
		{
			get
			{
				return m_AstronomicalObjectType;
			}
			set
			{
				m_AstronomicalObjectType = value;
			}
		}

		/// <summary>
		/// Gets or sets the type of the position.
		/// </summary>
		/// <value>The type of the position.</value>
		[Category("AstronomicalObject")]
		[Description("Gets or sets the type of the position.")]
		public PositionType PositionType
		{
			get
			{
				return m_PositionType;
			}
			set
			{
				m_PositionType = value;
			}
		}

		/// <summary>
		/// Gets or sets the speed in angles per hour that the object moves.
		/// </summary>
		/// <example>A speed of 15 is (15*24) or 360, so the object makes one full rotation around the Earth in 24 hours.</example>
		/// <value>The speed in angles per hour that the object moves.</value>
		[Category("AstronomicalObject")]
		[Description("Gets or sets the speed in angles per hour that the object moves.")]
		public double Speed
		{
			get
			{
				return m_Speed;
			}
			set
			{
				m_Speed = value;
			}
		}

		/// <summary>
		/// Gets or sets the current position of the location of the object.
		/// </summary>
		/// <value>The Position.</value>
		[Category("AstronomicalObject")]
		[Description("Gets or sets the current position of the location of the object.")]
		public Position Position
		{
			get
			{
				return m_Position;
			}
			set
			{
				m_Position = value;
			}
		}

		/// <summary>
		/// Gets or sets the magnitude.
		/// </summary>
		/// <value>The magnitude.</value>
		[Category("AstronomicalObject")]
		[Description("Gets or sets the magnitude of the object.")]
		public double Magnitude
		{
			get
			{
				return m_Magnitude;
			}
			set
			{
				m_Magnitude = value;
			}
		}

		/// <summary>
		/// Gets or sets the constellation that this astronomical object is a part of.  This can be null.
		/// </summary>
		/// <value>The constellation.</value>
		[Category("AstronomicalObject")]
		[Description("Gets or sets the constellation that this astronomical object is a part of.  This can be null.")]
		public string Constellation
		{
			get
			{
				return m_Constellation;
			}
			set
			{
				m_Constellation = value;
			}
		}

		/// <summary>
		/// Gets or sets the distance from the Earth.
		/// </summary>
		/// <value>The distance from the Earth.</value>
		[Category("AstronomicalObject")]
		[Description("Gets or sets the distance from the Earth.")]
		public double Distance
		{
			get
			{
				return m_Distance;
			}
			set
			{
				m_Distance = value;
			}
		}

		/// <summary>
		/// Gets or sets the distance unit used to represent the <see cref="Distance"/>.
		/// </summary>
		/// <value>The distance unit used to represent the distance.</value>
		[Category("AstronomicalObject")]
		[Description("Gets or sets the distance unit used to represent the distance.")]
		public ININ.Measurement.MetricLengthUnit DistanceUnit
		{
			get
			{
				return m_DistanceUnit;
			}
			set
			{
				m_DistanceUnit = value;
			}
		}

		/// <summary>
		/// Gets or sets the color that represents this <see cref="AstronomicalObject"/>.
		/// </summary>
		/// <value>The color of the representation.</value>
		[Category("Appearance")]
		[Description("Gets or sets the color that represents this AstronomicalObject.")]
		public string RepresentationColor
		{
			get
			{
				return m_RepresentationColor;
			}
			set
			{
				m_RepresentationColor = value;
			}
		}

		/// <summary>
		/// Gets or sets the diameter in pixels.
		/// </summary>
		/// <value>The diameter in pixels.</value>
		[Category("Appearance")]
		[Description("Gets or sets the diameter in pixels.")]
		public int DiameterInPixels
		{
			get
			{
				return m_DiameterInPixels;
			}
			set
			{
				m_DiameterInPixels = value;
			}
		}
		#endregion Public Properties

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="AstronomicalObject"/> class.
		/// </summary>
		public AstronomicalObject()
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AstronomicalObject"/> class.
		/// </summary>
		/// <param name="ID">The ID.</param>
		public AstronomicalObject(
			string ID)
			: this()
		{
			ININ.Guard.ArgumentNotNullOrEmptyString(ID, "ID");
			m_ID = ID;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AstronomicalObject"/> class.
		/// </summary>
		/// <param name="ID">The ID.</param>
		/// <param name="name">The name.</param>
		public AstronomicalObject(
			string ID,
			string name)
			: this(ID)
		{
			m_Name = name;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AstronomicalObject"/> class.
		/// </summary>
		/// <param name="ID">The ID.</param>
		/// <param name="name">The name.</param>
		/// <param name="representationColor">Color of the representation.</param>
		public AstronomicalObject(
			string ID, 
			string name,
			string representationColor)
			: this(ID, name)
		{
			m_RepresentationColor = representationColor;
		}
		#endregion Constructors
	} 
}
